#ifndef FORTRESS_ITEMS_H
#define FORTRESS_ITEMS_H
#include "libtcod.hpp"
#include <map>
#include <list>
#include <string>
#include <vector>

#include "glyph.h"

#include <boost/archive/text_oarchive.hpp>

namespace fortress
{
	class character;
	class parserListen;
	typedef std::list<void (*)(character *, std::string *)> event_t;
	class items : public glyph
	{
	private:
		friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int version);

		std::string name;	// This is used by the program to refer to an object
		std::string singular;	// When the view needs to display the name of one of these, it will say "a [singular]"
		std::string plural; // When the view needs to display the name of multiple of these, it will say "# [plural]"
		std::string description;
		int cost;	// The base cost, used by merchants and for scoring
		double weight;	// The amount the object weighs
		bool walkable;	// A flag for the player being able to walk on top of this
		bool canCarry;	// A flag for allowing characters to pick this up
		bool transparent;
		TCOD_dice_t baseDamage;	// The amount of damage this object deals
		TCOD_color_t color;	// The color this object is displayed with
		friend class parseListen;	// This builds item objects
		std::map<int,event_t> events;
		// Convert the item to another item type

	public:
		void convertItem(items const & itemData);

		items();
		~items();
		items & operator=(items const & copy);
		items(items const & copy);

		std::string getName() const { return name; };
		std::string getSingular() const { return singular; };
		std::string getPlural() const { return plural; };
		int getCost() const { return cost; };
		double getWeight() const { return weight; };
		bool getWalkable() const { return walkable; };
		bool getCanCarry() const { return canCarry; };
		bool getTransparent() const { return transparent; };
		void setName(std::string const & set) { name = set; };
		void setSingular(std::string const & set) { singular = set; };
		void setPlural(std::string const & set) { name = set; };
	};

	class itemFactory
	{
	private:
		TCODParser * parser;
	public:

		itemFactory();
		~itemFactory();
		std::map<int,items*> * readFile(char * filename);
		std::map<int,items*> * allItems;
//		void getItem(std::string & gName,std::string & gSingular, std::string & gPlural, std::string gDescription, int & gCost,
//			, double & gWeight, bool & gWalkable, bool & gCanCarry, bool & gTransparent,
			
	};
	struct abstractItems
	{
		friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int version);

		std::string name;
		std::string singular;
		std::string plural;
		std::string description;
		int cost;
		int weight;
		bool walkable;
		bool canCarry;
		bool transparent;
		int dice;
		int sides;
		std::string color;
		char glyph;
		std::map<int,event_t> events;
	};

	class savedItems
	{
	private:
		friend class boost::serialization::access;
		template<class Archive>
		void serialize(Archive & ar, const unsigned int version);

		std::vector<abstractItems> stored;
	public:
		savedItems(std::vector<abstractItems> items):
		  stored(items){ };
		  savedItems() { };
		  std::vector<abstractItems> getItems() { return stored; };

	};
};
#endif